#pragma once
#include <iostream>
#include <sys/types.h>
#include <sys/socket.h>
#include "Connection.hpp"
#include "Log.hpp"
#include "NetCal.hpp"
#include "IOService.hpp"

using namespace log_ns;

// using process_t = std::function<std::string(std::string&)>;

class HandlerConnection {
    const static int buff_size = 1028;

public:
    HandlerConnection(handler_t process)
        : _process(process)
    {}

    void HandlerReciver(Connection* conn) {
        // 开始接收消息
        errno = 0;
        // std::cout << "inbuffer: " << conn->GetInbuff() << std::endl;
        char buff[buff_size];
        while (true) {
            int n = recv(conn->Sockfd(), buff, sizeof(buff) - 1, 0);
            if (n > 0) {
                buff[n] = '\0';
                conn->AppendInbuff(buff);
            } else {
                if (errno == EWOULDBLOCK) {
                    LOG(INFO, "recive info over\n");
                    break;
                } else if (errno == EINTR) {
                    continue;
                } else {
                    
                    // LOG(ERROR, "recive info error, the reason is %s\n", strerror(errno));
                    // HandlerExcepter(conn);
                    conn->_handler_excepter(conn);
                    return;
                }
            }
        }

        if (conn->GetInbuff().empty()) return; 

        std::cout << "recive info:\n" << conn->GetInbuff() << std::endl;
        // 将发送过来的信息进行处理
        // HandlerExcepter(conn);

        _process(conn);
        conn->_handler_sender(conn);
    }

    void HandlerSender(Connection* conn) {
        // 现在将数据发送出去
        errno = 0;
        while (true) {
            std::string& info = conn->GetOutbuff();
            int n = send(conn->Sockfd(), info.c_str(), info.size(), 0);
            if (n > 0) {
                conn->DecreaseOutbuff(n);
                if (info.empty())
                    break;
            } else if (n == 0) {
                break;
            } else {
                if (errno == EWOULDBLOCK) {
                    // 发送条件不满足
                    break;
                }
                else if (errno == EINTR) {
                    continue;
                }
                else {
                    conn->_handler_excepter(conn);
                    return;
                }
                    
            }  
        }
        
        if (!conn->GetOutbuff().empty()) {
            // 还没发送结束，还需要继续发送
            // 但是当前发送条件已经不满住，需要重新设置
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, true);
        } else {
            conn->_R->EnableConnectionReadWrite(conn->Sockfd(), true, false);
        }
    }

    void HandlerExcepter(Connection* conn) {
        // 对于异常的处理，都是将连接关闭
        conn->_R->CloseReactorSocket(conn);
    }

private:
    handler_t _process;
};